Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.

...powered by www.netzwerkartist.de...

 << zurück
Visual C# 2005 von Andreas Kühnel
Das umfassende Handbuch
Buch: Visual C# 2005

Visual C# 2005
1.320 S., mit 2 CDs, 59,90 Euro
Galileo Computing
ISBN 3-89842-586-X
gp Kapitel 18 Menü-, Symbol- und Statusleiste
  gp 18.1 Das Steuerelement »ToolStripContainer«
  gp 18.2 Bereitstellen eines Menüs
    gp 18.2.1 Die Hierarchie der Menüklassen
    gp 18.2.2 Das Erzeugen eines Menüs
    gp 18.2.3 Die Eigenschaften der Menüelemente »ToolStripMenuItem«
    gp 18.2.4 »ToolStripComboBox« und »ToolStripTextBox«
    gp 18.2.5 Ereignisse
    gp 18.2.6 Beispielprogramm
  gp 18.3 Kontextmenüs
    gp 18.3.1 Das Standardverhalten eines Kontextmenüs ändern
    gp 18.3.2 Ereignisse des Kontextmenüs
    gp 18.3.3 Das Kontextmenü einer Textbox
  gp 18.4 Die Zwischenablage
    gp 18.4.1 Speichern und Abrufen von Daten aus der Zwischenablage
    gp 18.4.2 Andere Methoden, um Daten in die Zwischenablage zu schreiben und abzurufen
    gp 18.4.3 Mehrere Datenformate in der Zwischenablage
    gp 18.4.4 Eigene Datenformate in die Zwischenablage schreiben
    gp 18.4.5 Beispielprogramm – das Menü »Bearbeiten«
  gp 18.5 Die Symbolleiste
    gp 18.5.1 Die Eigenschaften der Symbolleistenschaltflächen
    gp 18.5.2 Drop-down-Buttons in Symbolleisten
    gp 18.5.3 Ein Zwitter vom Typ »ToolStripSplitButton«
    gp 18.5.4 Comboboxen in Symbolleisten
    gp 18.5.5 Textboxen in Symbolleisten
    gp 18.5.6 Fortschrittsbalken (ProgressBar)
    gp 18.5.7 Die Ereignisse der Symbolleiste programmieren
    gp 18.5.8 Beispiel einer komplexeren Symbolleiste
  gp 18.6 Die Statusleiste
    gp 18.6.1 Eine Statusleiste bereitstellen
    gp 18.6.2 Die in der Statusleiste integrierten Steuerelemente


Galileo Computing

18.4 Die Zwischenablage  downtop

In der .NET-Klassenbibliothek wird die Zwischenablage durch die Klasse Clipboard beschrieben. Die Klasse enthält keine öffentlichen Konstruktoren und kann demnach nicht instanziiert werden. Verglichen mit .NET 1.0/1.1 ist die Klasse um zahlreiche statische Methoden erweitert worden, die das Programmieren der Zwischenablage komfortabler und einfacher machen.


Galileo Computing

18.4.1 Speichern und Abrufen von Daten aus der Zwischenablage  downtop

Die beiden allgemeinsten Methoden der Klasse Clipboard sind GetDataObject und SetDataObject, die den Datenaustausch in einem nicht festgeschriebenen Format erlauben. GetDataObject liest den Inhalt der Zwischenablage aus, die mehrfach überladene Methode SetDataObject schreibt die Daten hinein.


public static IDataObject GetDataObject();
public static void SetDataObject(object);
public static void SetDataObject(object, bool);

Das Speichern von Daten in der Zwischenablage mit »SetDataObject«

Wollen Sie eine Zeichenfolge in die Zwischenablage schreiben, übergeben Sie diese einfach der SetDataObject-Methode:


Clipboard.SetDataObject("Dies ist eine Zeichenfolge.");

Da der Parameter vom Typ object ist, beschränkt sich die Übergabe aber nicht nur auf Zeichenfolgen. Sie können beliebige Objekte ablegen, beispielsweise auch die Referenz auf eine Bitmap:


Clipboard.SetDataObject(myBitmap);

Ein wiederholter Aufruf von SetDataObject hat zur Folge, dass der aktuelle Inhalt der Zwischenablage durch einen neuen überschrieben wird.

Der optionale boolesche Parameter der überladenen Methode SetDataObject gibt an, ob die Daten nach dem Beenden der Anwendung in der Zwischenablage bleiben sollen (true) oder nicht (false). Die Standardvorgabe ist false. Das hat jedoch auch noch eine anderweitige Konsequenz. Übergeben Sie nämlich dem zweiten Parameter true, enthält die Zwischenablage eine Kopie des Objekts. Die Folge davon ist, dass bei einer Änderung des Objekts der Inhalt der Zwischenablage unberührt bleibt.

Mit


Clipboard.SetDataObject(obj, false);

wird die Referenz auf das Objekt obj in die Zwischenablage geschrieben. Änderungen am Objekt wirken sich dann auch auf die Zwischenablage aus.


Hinweis   Voraussetzung dafür, ein Objekt der Zwischenablage übergeben zu können, ist die Serialisierbarkeit der Klasse.

Das Abrufen von Daten aus der Zwischenablage mit »GetDataObject«

Etwas komplexer ist das Abrufen der in der Zwischenablage befindlichen Daten. Das wird bereits klar, wenn Sie sich die Definition der Methode GetDataObject ansehen: Der Rückgabewert liefert ein Objekt, das die Schnittstelle IDataObject implementiert. Über die Methoden der Schnittstelle können weitere Informationen abgerufen werden.

Nehmen wir an, dass wir uns mit


IDataObject myData = Clipboard.GetDataObject();

den Inhalt aus der Zwischenablage holen. Auf die Referenz myData vom Typ der Schnittstelle IDataObject können wir vier Methoden aufrufen, die alle überladen sind. In Tabelle 18.2 sind die Methoden aufgeführt und die Verhaltensweisen beschrieben.


Tabelle 18.2   Methoden der Schnittstelle »IDataObject«

Methode Beschreibung
GetData Ruft die Daten aus der Zwischenablage ab.
GetDataPresent Überprüft das Datenformat in der Zwischenablage.
GetFormats Gibt eine Liste aller in der Zwischenablage gespeicherten Formate zurück.
SetData Speichert Daten in einem bestimmten Format in der Zwischenablage.

Betrachten wir den einfachsten und den in der Praxis vermutlich auch am häufigsten auftretenden Fall, dass in der Zwischenablage eine Zeichenfolge abgelegt ist, die abgerufen werden soll. Dazu sind zwei Anweisungen notwendig:


IDataObject myData = Clipboard.GetDataObject();
textBox1.Text = (string)myData.GetData(typeof(string));

Mit der ersten Anweisung besorgen wir uns die Referenz auf ein Objekt vom Typ IDataObject und rufen darauf in der zweiten Anweisung die Methode GetData auf, der wir zur Identifizierung den Datentyp mit typeof übergeben. Damit können die Daten im richtigen Format ausgelesen werden. Den Wert, den uns GetData liefert, müssen wir noch in den entsprechenden Datentyp konvertieren.

Die Definition der im Codefragment benutzten GetData-Methode lautet:


public object GetData(Type);

Es gibt noch zwei weitere Überladungen, die anstelle der Type-Referenz eine Zeichenfolge entgegennehmen:


public object GetData(string format);
public object GetData(string format, bool);

Damit ist es auch möglich, sich den Inhalt der Zwischenablage mit

textBox1.Text = (string)myData.GetData("System.String");

zu besorgen. Dabei gehen wir davon aus, dass die Daten auch als Zeichenfolge interpretierbar sind. Liegt ein anderes Datenformat vor, kann mit dem booleschen Parameter versucht werden, in das angegebene Format zu konvertieren. Dazu wird dem booleschen Parameter true übergeben.


textBox1.Text = (string)myData.GetData("System.String", true);

Wollen Sie ermitteln, ob die Zwischenablage Daten enthält, die von Ihrer Anwendung verarbeitet werden können, muss die Verwertbarkeit überprüft werden. Dazu dient die Methode GetDataPresent.


public bool GetDataPresent(Type);
public bool GetDataPresent(string);
public bool GetDataPresent(string, bool);

Der Aufruf von


Clipboard.GetDataObject().GetDataPresent(typeof(string))

gibt beispielsweise true zurück, wenn die Zwischenablage Daten im string-Format enthält.

GetDataPresent eignet sich wegen des booleschen Rückgabewerts insbesondere als Bedingungsausdruck in eine if-Anweisung.


IDataObject myData = Clipboard.GetDataObject();
if (myData.GetDataPresent(typeof(ClassA)))
  // Anweisungen
else if (myData.GetDataPresent(typeof(string)))
  textBox1.Text = (string)myData.GetData(typeof(string));

Sie können das Format der Daten abfragen, indem Sie eine Type-Referenz oder eine Zeichenfolge übergeben. Beispielsweise sind die beiden folgenden Ausdrücke gleichwertig:


myData.GetDataPresent(typeof(string))
myData.GetDataPresent("System.String")

Eine dritte Variante besteht darin, eine der statischen Eigenschaften der Klasse DataFormats zu übergeben, welche die von .NET unterstützten Zwischenablageformate als Zeichenfolgen zurückgeben. Mit


IDataObject myData = Clipboard.GetDataObject();
if (myData.GetDataPresent(DataFormats.Text))
  MessageBox.Show((string)Clipboard.GetDataObject().GetData(DataFormats.Text));

können Sie beispielsweise zuerst den Inhalt der Zwischenablage daraufhin untersuchen, ob er im Textformat vorliegt, und sich diesen anschließend in einem Meldungsfenster ausgeben lassen.

In der folgenden Tabelle finden Sie eine Auswahl der statischen Felder der Klasse DataFormats, die zum Namespace System.Windows.Forms gehört.


Tabelle 18.3   Statische Felder der Klasse »DataFormats« (Auszug)

Member Beschreibung
Bitmap Beschreibt das Windows-Bitmap-Format.
Html Beschreibt Text, der aus HTML-Daten besteht.
Text Beschreibt das standardmäßige ANSI-Textformat.
UnicodeText Beschreibt das standardmäßige Unicode-Textformat von Windows.


Galileo Computing

18.4.2 Andere Methoden, um Daten in die Zwischenablage zu schreiben und abzurufedowntop

GetDataObject und SetDataObject sind hinsichtlich des Datentyps sehr allgemein gehalten. Mehrere SetXxx-Methoden gestatten es, Daten eines bestimmten Formats in die Zwischenablage zu schreiben. Mit den analogen Methoden GetXxx kann der Inhalt der Zwischenablage ausgelesen werden. Ist das Datenformat nicht bekannt, können Sie dieses mit ContainsXxx-Methoden prüfen.


Tabelle 18.4   Methoden der Klasse »Clipboard«

Methode Beschreibung
ContainsAudio Gibt an, ob in der Zwischenablage Daten im WaveAudio-Format vorliegen.
ContainsData Gibt an, ob in der Zwischenablage Daten in einem spezifizierten Format vorliegen oder in dieses konvertiert werden können.
ContainsFileDropList Gibt an, ob in der Zwischenablage Dateien eines Drag & Drop-Vorgangs aus der Windows Shell vorliegen
ContainsImage Gibt an, ob in der Zwischenablage Daten im Bitmap-Format vorliegen oder in dieses konvertiert werden können.
ContainsText Gibt an, ob in der Zwischenablage Daten im Textformat vorliegen.
GetAudioStream Liefert die Audiostreams aus der Zwischenablage.
GetData Liefert die Daten im spezifizierten Format aus der Zwischenablage.
GetFileDropList Liefert eine Collection aller Dateinamen aus der Zwischenablage.
GetImage Liefert ein Image aus der Zwischenablage.
GetText Liefert Text aus der Zwischenablage.
SetAudio Schreibt Daten im WaveAudio-Format in die Zwischenablage.
SetData Schreibt Daten in einem spezifizierten Format in die Zwischenablage.
SetFileDropList Schreibt eine Auflistung von Dateinamen in die Zwischenablage.
SetImage Schreibt ein Image in die Zwischenablage.
SetText Schreibt Text in die Zwischenablage.

Der Einsatz der Methoden ist ausgesprochen simpel. Legen Sie darauf Wert, die Zwischenablage nur dann auszuwerten, wenn sie ein bestimmtes Datenformat beherbergt, fragen Sie das mit einer der ContainsXxx-Methoden ab. Ist das Ergebnis positiv, also true, rufen Sie die Daten mit der entsprechenden GetXxx-Methode ab.


private void btmShowClipboard_Click(object sender, EventArgs e) {
  if (Clipboard.ContainsText())
    MessageBox.Show(Clipboard.GetText());
  else
    MessageBox.Show("Zwischenablage enthält keine Daten im Text-Format.");
}


Galileo Computing

18.4.3 Mehrere Datenformate in der Zwischenablage  downtop

Normalerweise kann in der Zwischenablage immer nur ein Element gleichzeitig gespeichert werden. Dazu verwenden Sie die Methode SetXxx. Es ist allerdings möglich, ein bestimmtes Element in mehreren Formaten oder mehrere Elemente unterschiedlicher Formate in die Zwischenablage zu kopieren. Der Weg dazu führt über ein Objekt vom Typ DataObject. Dieser Typ, den man als Container für Elemente unterschiedlicher Formate ansehen kann, implementiert die IDataObject-Schnittstelle. Damit werden auch alle Methoden dieser Schnittstelle unterstützt, von denen für uns SetData von besonderem Interesse ist.

SetData speichert Daten in einem bestimmten Format im DataObject-Objekt. Dazu stehen mehrere Überladungen zur Verfügung.


public void SetData(object data);
public void SetData(Type type, object data);
public void SetData(string format, object data);
public void SetData(string format, bool convert, object data);

Dem string-Parameter können Sie auch in diesem Fall eine Konstante der Klasse DataFormats übergeben.

Der Einsatz der Methode ist sehr einfach. Zuerst erzeugen Sie ein DataObject-Objekt und rufen auf dessen Referenz die Methode SetData auf, der Sie jeweils Elemente unterschiedlichen Formats übergeben. Damit befindet sich der Inhalt natürlich noch nicht in der Zwischenablage, denn dazu ist der Aufruf der Methode SetDataObject der Clipboard-Klasse zuständig, der das DataObject-Objekt übergeben wird.


DataObject data = new DataObject();
data.SetData(DataFormats.Text, "Irgendeine Zeichenfolge");
Clipboard.SetDataObject(data);

Sollen mehrere unterschiedliche Formate der Zwischenablage übergeben werden, muss SetData mehrfach aufgerufen werden. Sehen wir uns dazu ein Beispiel an, bei dem der Zwischenablage sowohl ein Bitmap als auch eine Zeichenfolge übergeben wird.


// --------------------------------------------------------------
// Beispiel: ...\Kapitel 18\DataObjectDemo
// --------------------------------------------------------------
public partial class Form1 : Form {
  private Bitmap myBitmap;
  public Form1() {
    InitializeComponent();
    int width = pictureBox1.ClientSize.Width;
    int height = pictureBox1.ClientSize.Height;
    DataObject data = new DataObject();
    // Bitmap erzeugen 
    myBitmap = new Bitmap(width, height);
    Graphics g = Graphics.FromImage(myBitmap);
    g.FillRectangle(new SolidBrush(Color.White), 0, 0, width, height);
    g.DrawLine(new Pen(Color.Blue, 4), 0, 0, width, height);
    g.DrawLine(new Pen(Color.Red, 4), width, 0, 0, height);
    // Bitmap in die Zwischenablage kopieren
    data.SetData(DataFormats.Bitmap, myBitmap);
    // zusätzlichen Text in die Zwischenablage kopieren
    data.SetData(DataFormats.Text, "Feuchtfröhliche Feier");
    // DataObject-Objekt der Zwischenablage übergeben
    Clipboard.SetDataObject(data);
  }
  private void btnShowClipboard_Click(object sender, EventArgs e) {
    IDataObject dataObj = Clipboard.GetDataObject();
    // Bitmap aus der Zwischenablage in die Picturebox kopieren
    if(dataObj.GetDataPresent(DataFormats.Bitmap))
      pictureBox1.Image = (Bitmap)dataObj.GetData(DataFormats.Bitmap);
    // Text aus der Zwischenablage in die Textbox kopieren
    if(dataObj.GetDataPresent(DataFormats.Text))
      textBox1.Text = (string)dataObj.GetData(DataFormats.Text);
  }
}

Im Konstruktor der Form wird nach der Initialisierungsroutine programmatisch ein Bitmap in weißer Hintergrundfarbe und mit zwei Diagonalen erzeugt. Das Bitmap wird dem DataObject-Objekt übergeben, zusätzlich auch noch eine Zeichenfolge. Zum Schluss wird das DataObject-Objekt in die Zwischenablage geschrieben.

Die Form enthält neben einer Schaltfläche eine Picturebox und eine Textbox. Wird auf die Schaltfläche geklickt, wird der Inhalt der Zwischenablage einer Typuntersuchung unterzogen mit dem Ergebnis, dass das Bitmap in der Picturebox angezeigt wird und die Zeichenfolge in der Textbox (siehe Abbildung 18.9).

Abbildung
Hier klicken, um das Bild zu vergrößern

Abbildung 18.9   Ausgabe des Beispielprogramms »DataObjectDemo«

Schließen Sie die Anwendung, geht der Inhalt der Zwischenablage verloren. Wollen Sie, dass beispielsweise das Bitmap auch danach noch von einer anderen Anwendung wie MS Paint aus der Zwischenablage geholt werden kann, muss das DataObject-Object mit


Clipboard.SetDataObject(data, true);

der Zwischenablage übergeben werden.


Galileo Computing

18.4.4 Eigene Datenformate in die Zwischenablage schreiben  downtop

Die Klasse DataFormats definiert eine Reihe von Formaten. Sie sind aber nicht ausschließlich an diese Liste gebunden, sondern können auch eigene Datentypen in die Zwischenablage kopieren. Dabei kommt die dreiparametrige Variante der Methode SetData zum Einsatz. Der erste Parameter empfängt den Namen des neuen Datenformats, der boolesche Parameter gibt Auskunft darüber, ob die Konvertierung in ein anderes Format zulässig ist, und dem dritten Parameter werden die zu kopierenden Daten übergeben.

Nehmen wir an, es wäre der Typ ClassA wie folgt definiert:


[Serializable] class ClassA {
  public int Number;
  public string Name;
}

Beachten Sie, dass Typen, welche die Fähigkeit besitzen sollen, in die Zwischenablage kopiert zu werden, das Attribut Serializable aufweisen müssen.

Mit dem folgenden Code können wir ein Objekt des benutzerdefinierten Typs ClassA in die Zwischenablage kopieren:


ClassA obj = new ClassA();
obj.Number = 5500;
obj.Name = "Pelztier";
DataObject data = new DataObject();
data.SetData("ClassA", true, obj);
Clipboard.SetDataObject(data, true);

Dem SetDataObject-Aufruf übergeben wir true. Daher kann auch nach dem Beenden der aktuellen Anwendung eine andere Anwendung die Daten auswerten – vorausgesetzt, der Anwendung ist der Typ ClassA bekannt.

Die Daten aus der Zwischenablage zu lesen, ist sehr einfach:


IDataObject dataObj = Clipboard.GetDataObject();
if(dataObj.GetDataPresent("ClassA")) {
  ClassA obj = (ClassA)dataObj.GetData("ClassA");
  MessageBox.Show(obj.Number.ToString() + "\n"  + obj.Name);
}

Das Leeren der Zwischenablage erfolgt mit dem Aufruf der Methode Clear:


Clipboard.Clear();


Galileo Computing

18.4.5 Beispielprogramm – das Menü »Bearbeiten«  toptop

Kommen wir nun zum Ausgangspunkt zurück, der dazu führte, dass wir uns mit der Programmierung der Zwischenablage beschäftigt haben. Wir wollten einer Textbox ein Kontextmenü bereitstellen, in dem die Menüelemente Ausschneiden, Kopieren und Einfügen implementiert sind. Dazu ergänzen wir das in Abschnitt 18.2.6 begonnene Beispielprogramm, in dem wir auch noch nicht die gleichlautenden Untermenüs von Bearbeiten codiert haben.


// --------------------------------------------------------------
// Beispiel: ...\Kapitel 18\ContextMenuDemo
// --------------------------------------------------------------
public Form1() {
  InitializeComponent();
  Clipboard.Clear();
}

Der Konstruktor ist um eine Anweisung ergänzt, welche die Zwischenablage beim Start der Anwendung leert. Das ist keine Notwendigkeit, sondern dient nur dazu, das Verhalten des Menüelements Einfügen besser verfolgen zu können.

Sehen wir uns nun den Ereignishandler an, der markierten Text aus einer Textbox in die Zwischenablage schreibt.


private void menuKopieren_Click(object sender, EventArgs e) {
  Clipboard.SetText
    (((TextBox)(((ToolStripContainer)this.ActiveControl).
    ActiveControl)).SelectedText);
}

Nur eine, wenn auch ausgesprochen lange Anweisung ist dazu da, nämlich der Aufruf der Methode SetText. Bevor der Methode aber die markierte Zeichenfolge übergeben werden kann, ist eine zweimalige Konvertierung notwendig. Hintergrund dafür ist, dass der Arbeitsbereich der Form vollständig durch einen anderen Container in Anspruch genommen wird, nämlich das ToolStripContainer-Objekt, in dem sich sämtliche Controls der Form versammeln, auch die beiden Textboxen.

Der einfache Aufruf von


this.ActiveControl

liefert dann nicht, wie zunächst zu erwarten wäre, die Referenz auf die Textbox, die offensichtlich aktiv ist, sondern die Referenz auf das ToolStripContainer-Objekt. Da wir über dieses Objekt an die Textbox gelangen wollen, ist die erste Konvertierung notwendig:


(ToolStripContainer)this.ActiveControl

Nun haben wir die gewünschte Referenz auf den ToolStripContainer, der als Containerelement seinerseits selbst die Eigenschaft ActiveControl aufweist. Da sich im Container nur zwei Textboxen befinden, können wir hier bedenkenlos in den Typ TextBox konvertieren.


(TextBox)(((ToolStripContainer)this.ActiveControl).ActiveControl)

Jetzt stehen uns alle Methoden und Eigenschaften einer Textbox zur Verfügung, von denen SelectedText die markierte Zeichenfolge liefert.

Eine ähnlich aufwändige Konvertierung ist auch zum Ausschneiden des markierten Textes notwendig, der anschließend mit SetText in die Zwischenablage geschrieben wird.


private void menuAusschneiden_Click(object sender, EventArgs e) {
  TextBox txt = (TextBox)((ToolStripContainer)this.ActiveControl).ActiveControl;
  Clipboard.SetText(txt.SelectedText);
  // Cursorposition merken
  int cursorPosition = txt.SelectionStart;
  this.Ausschneiden(txt);
  // Eingabecursor positionieren 
  txt.SelectionStart = cursorPosition; 
}

Üblicherweise bleibt nach dem Ausschneiden der Cursor an seiner Position stehen. Deshalb merken wir uns in der Variablen cursorPosition diese und setzen nach der Zeichenfolgemanipulation den Cursor wieder passend ein. Würden wir darauf verzichten, wäre der Cursor vor dem ersten Zeichen positioniert.

Das Ausschneiden des markierten Textes und das neuerliche Zusammensetzen der Restzeichenfolge erfolgt in der Methode Ausschneiden. Diese erwartet die Referenz auf die Textbox, aus der die markierte Teilzeichenfolge ausgeschnitten werden soll.


// Ausschneiden des markierten Texts
private void Ausschneiden(TextBox txt) {
  int iLength = txt.SelectionLength + txt.SelectionStart;
  txt.Text = txt.Text.Substring(0, txt.SelectionStart) + 
          txt.Text.Substring(iLength, txt.Text.Length – iLength);
}

Das Einfügen eines Textes ist schon etwas aufwändiger. Wir müssen dabei zwei Dinge berücksichtigen:

gp  Ist kein Text in der Textbox markiert, in die der Inhalt der Zwischenablage geschrieben werden soll, wird die Position des Cursors als Einfügeposition bewertet.
gp  Sollte in der Textbox Text markiert sein, muss dieser durch den Inhalt der Zwischenablage ersetzt werden.

Nach dem Einfügen gilt es, die neue Zeichenfolge zu bilden und den Cursor an das Ende des eingefügten Textes zu setzen.


private void menuEinfuegen_Click(object sender, EventArgs e) {
  TextBox txt = 
 (TextBox)((ToolStripContainer)this.ActiveControl).ActiveControl;
  // Cursorposition merken
  int cursorPosition = txt.SelectionStart;
  // falls markierter Text durch den Inhalt der Zwischenablage ersetzt werden soll
  if (txt.SelectedText.Length > 0) 
    this.Ausschneiden(txt);
  // Teilstrings links und rechts des Cursors bestimmen
  string strLinks = txt.Text.Substring(0, cursorPosition);
  string strRechts = txt.Text.Substring(cursorPosition,  
                              txt.Text.Length – cursorPosition);
  // Inhalt der Zwischenablage abrufen
  string strClip = Clipboard.GetText();
  // neue Zeichenfolge zusammensetzen
  txt.Text = strLinks + strClip + strRechts;
  // Eingabecursor hinter dem eingefügten Text positionieren 
  txt.SelectionStart = cursorPosition + strClip.Length;
}

Markierter Text wird mit dem Menüelement Löschen ausgeschnitten, aber nicht der Zwischenablage übergeben. Die Cursorposition ist anschließend zwischen den beiden verbleibenden Teilstrings. Für das Ausschneiden hatten wir weiter oben eine gleichnamige Methode bereitgestellt.


private void menuLoeschen_Click(object sender, EventArgs e) {
  TextBox txt = 
 (TextBox)((ToolStripContainer)this.ActiveControl).ActiveControl;
  // Startposition des Cursors merken
  int cursorPosition = txt.SelectionStart;
  this.Ausschneiden(txt);
  // Cursor setzen
  txt.SelectionStart = cursorPosition;
}

Unabhängig davon, ob der Benutzer sich des Anwendungs- oder Kontextmenüs bedient, um den Inhalt einer Textbox zu verändern, die Funktionalitäten Ausschneiden, Kopieren, Löschen und Einfügen bleiben dieselben. Daher werden die Click-Ereignisse der Menüelemente des Kontextmenüs mit den entsprechenden Ereignishandlern des Anwendungsmenüs verknüpft.

Das Ereignis DropDownOpening wird ausgelöst, ehe das angeklickte Menüelement sein Untermenü öffnet. Wir nutzen dieses Ereignis des Menüpunktes Bearbeiten, um festzustellen, ob

gp  sich einfügbarer Text in der Zwischenablage befindet. Wenn nicht, kann der Menüpunkt Einfügen deaktiviert werden.
gp  in der aktiven Textbox kein Text markiert ist. In dem Fall gibt es nichts zu löschen, auszuschneiden oder in die Zwischenablage zu kopieren. Dann können die Menüpunkte Ausschneiden, Löschen und Kopieren deaktiviert angezeigt werden.

Diese Prüfungen vollzieht der Ereignishandler des DropDownOpening-Ereignisses.


private void menuBearbeiten_DropDownOpening(object sender, EventArgs e) {
  TextBox txt = 
 (TextBox)((ToolStripContainer)this.ActiveControl).ActiveControl;
  // Prüfen, ob sich in der Zwischenablage textuelle Daten befinden
  if (!Clipboard.ContainsText())
    menuEinfuegen.Enabled = false;
  else
    menuEinfuegen.Enabled = true;
  // Prüfen, ob Text in der aktiven Textbox markiert ist
  if (txt.SelectedText == "") {
    menuKopieren.Enabled = false;
    menuAusschneiden.Enabled = false;
    menuLoeschen.Enabled = false;
  }
  else {
    menuKopieren.Enabled = true;
    menuAusschneiden.Enabled = true;
    menuLoeschen.Enabled = true;
  }
}

Analog wird auch die Aktivierung der Menüelemente des Kontextmenüs gesteuert. Dazu dient uns das Ereignis Opening.

 


private void contextMenuStrip1_Opening(object sender, CancelEventArgs e) {
  TextBox txt = 
(TextBox)((ToolStripContainer)this.ActiveControl).ActiveControl;
  // Prüfen, ob sich in der Zwischenablage textuelle Daten befinden
  if (!Clipboard.ContainsText())
    conEinfuegen.Enabled = false;
  else
    conEinfuegen.Enabled = true;
  // es ist kein Text in der aktiven Textbox markiert
  if (txt.SelectedText == "") {
    conKopieren.Enabled = false;
    conAusschneiden.Enabled = false;
    conLoeschen.Enabled = false;
  }
  else {
    conKopieren.Enabled = true;
    conAusschneiden.Enabled = true;
    conLoeschen.Enabled = true;
  }
}

Kommen wir jetzt zum letzten Schritt. Im Kontextmenü wird ebenfalls die Änderung der Hintergrundfarbe angeboten. Wir müssen die Methode ChangeColor, die auch diesen Menüelementen als Ereignishandler dient, so ergänzen, dass eine Änderung der Farbe auch vom entsprechenden Kontextmenüelement verzeichnet wird.


// Ereignishandler der Click-Ereignisse der Menüelemente, mit denen
// die Hintergrundfarbe der Textboxen geändert werden kann
private void ChangeColor(object sender, EventArgs e) {
  foreach (ToolStripMenuItem temp in conHintergrundfarbe.DropDownItems)
    temp.Checked = false;
  foreach (ToolStripMenuItem temp in menuHintergrundfarbe.DropDownItems)
    temp.Checked = false;
  switch (((ToolStripMenuItem)sender).Text) {
    case "Weiß":
      txtOben.BackColor = Color.White;
      txtUnten.BackColor = Color.White;
      conWeiss.Checked = true;
      menuWeiss.Checked = true;
      break;
    case "Rot":
      ...
  }
}

 << zurück
  
  Zum Katalog
Zum Katalog: Visual C# 2005
Visual C# 2005
bestellen
 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: Fortgeschrittene Programmierung mit Visual C# 2005






 Fortgeschrittene
 Programmierung
 mit Visual C# 2005


Zum Katalog: Einstieg in Visual C# 2005






 Einstieg in
 Visual C# 2005


Zum Katalog: Einstieg in Visual Basic 2005






 Einstieg in
 Visual Basic 2005


Zum Katalog: Visual Basic 2005






 Visual Basic 2005


Zum Katalog: Java ist auch eine Insel






 Java ist auch eine
 Insel


Zum Katalog: Konzepte und Lösungen für Microsoft-Netzwerke






 Konzepte und
 Lösungen für
 Microsoft-Netzwerke


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo








Copyright © Galileo Press 2006
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Galileo Computing]

Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de